home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / src / mactech / volume14_1998 / 14.12.sit / 14.12 / Poor Man's Bryce 3.0 / Image.c next >
Text File  |  1998-06-24  |  6KB  |  197 lines

  1. // Image.c
  2. // ©1998 Kas Thomas. Portions © Xplain Corp.
  3. // Use at your own risk.
  4. //
  5. // Purpose of module:
  6. // QuickTime routines for image handling.
  7. //
  8. // NOTE:
  9. // You will need to soft-link to the latest QuickTimeLib module
  10. // in order to avoid link-time errors with this set of routines.
  11. // Get QuickTime 3.0!
  12.  
  13. #include <ImageCompression.h>
  14. #include <math.h>
  15. #include <QDOffscreen.h>
  16.  
  17. #include "Image.h"
  18.  
  19. #define HALVE_RECT(r) { r.right /= 2; r.bottom /= 2; }
  20. #define MULTIPLY_RECT(r,f) { r.left *= f; r.right *=f; r.bottom *=f; r.top *=f; }
  21. #define RECT_AREA(r) ( (r.right-r.left)*(r.bottom-r.top) )
  22. #define MARGIN 50
  23.  
  24.  
  25. // ------------------------- DrawMyGraphicsFile() ------------------------
  26. // Using QuickTime's ImageCompression.h and Component.h routines, try to
  27. // open whatever image file the user has specified and display the image
  28. // in an appropriately sized window.
  29.  
  30. void DrawMyGraphicsFile(const FSSpec *fss)
  31. {
  32.     GraphicsImportComponent gi;
  33.     Rect                    naturalBounds;
  34.     long                    err;
  35.     extern WindowPtr        gImageWindow;
  36.     extern void             TellUser(Str255 errmsg, OSErr errcode );
  37.     
  38.     
  39.     err = GetGraphicsImporterForFile(fss, &gi);  // see if QT can handle the file
  40.     if (err) {
  41.         TellUser("\pSorry, can't open this file.", err);
  42.         return;
  43.         }
  44.                                                 // get native dimensions of image
  45.     err = GraphicsImportGetNaturalBounds (gi,&naturalBounds); 
  46.     if (err)
  47.         SetRect(&naturalBounds, MARGIN,MARGIN,400,400);
  48.         
  49.                                                 // if too big to fit screen, downsize
  50.     while (naturalBounds.right + MARGIN > (**GetMainDevice()).gdRect.right)
  51.         HALVE_RECT(naturalBounds);
  52.         
  53.     while (naturalBounds.bottom + MARGIN > (**GetMainDevice()).gdRect.bottom)
  54.         HALVE_RECT(naturalBounds);
  55.         
  56.     OffsetRect(&naturalBounds,MARGIN,MARGIN);    // allow some breathing room
  57.     
  58.     gImageWindow = NewCWindow(nil,                // create proper size window
  59.                              &naturalBounds,
  60.                              fss->name,
  61.                              true,
  62.                              noGrowDocProc,
  63.                              (WindowPtr)-1,
  64.                              true,
  65.                              0) ;
  66.                                     
  67.     GraphicsImportSetBoundsRect(gi, &naturalBounds); // tell QT the destination rect bounds
  68.     err=GraphicsImportDraw(gi);                        // tell QT to draw the image into the rect
  69.     CloseComponent(gi);                            // tell QT we're done with the importer
  70. }
  71.  
  72. // ------------------------- GetMyGraphicsFile() ------------------------
  73. // Prompt user for a graphics file.
  74. void GetMyGraphicsFile(StandardFileReply    *reply) 
  75. {    
  76.     OSType     imageFormats[] = {  'TIFF', 
  77.                                 'GIFf', 
  78.                                 'gif ', 
  79.                                 'JPEG', 
  80.                                 'PICT', 
  81.                                 '8BPS' } ;
  82.                                 
  83.     StandardGetFilePreview(nil, 6, imageFormats, reply);
  84. }
  85.  
  86.  
  87.  
  88. // ------------------------- GetMyGraphicsFilePixmap() ------------------------
  89. PixMapHandle    GetMyGraphicsFilePixmap(const FSSpec *fss, long maxPixelLimit) 
  90. {
  91.     PixMapHandle            offPix;
  92.     long                    err, pixelCount;
  93.     double                    shrinkFactor;
  94.     Rect                    imageBounds;
  95.     GraphicsImportComponent gi;
  96.     CGrafPtr                curPort,newPort;
  97.     GDHandle                curDevice,newDevice;
  98.     extern GWorldPtr        gOffScreenGWorld;
  99.     
  100.     
  101.     GetGWorld( &curPort, &curDevice );            // get current state
  102.     
  103.     err = GetGraphicsImporterForFile(fss, &gi);  // see if QT can handle the file
  104.     if (err) {
  105.         TellUser("\pSorry, can't open this file.", err);
  106.         return nil;
  107.         }
  108.                                                 // get native dimensions of image
  109.     err = GraphicsImportGetNaturalBounds (gi,&imageBounds); 
  110.     if (err) {
  111.         TellUser("\pCan't get image bounds.", err);
  112.         return nil;
  113.         }
  114.                                                 // how many pixels?
  115.     pixelCount = (imageBounds.right - imageBounds.left) * 
  116.         (imageBounds.bottom - imageBounds.top);
  117.  
  118.     if (pixelCount > maxPixelLimit) {            // are we over the limit?
  119.         
  120.         shrinkFactor = (double)maxPixelLimit/pixelCount;  // find pixel reduction factor
  121.         shrinkFactor = sqrt( shrinkFactor );              // get square root
  122.         
  123.         MULTIPLY_RECT(imageBounds,shrinkFactor);          // subsample the dest rect down
  124.         }
  125.                         
  126.     // NOTE: We preflight our memory situation now. Important to do this, because
  127.     // NewGWorld (our next call, below) doesn't fail gracefully if memory is low.
  128.     if (TempFreeMem() < RECT_AREA(imageBounds) + 1000)    {         
  129.         CloseComponent(gi);    
  130.         TellUser("\pNot enough memory to do this right now.", 0);
  131.         return nil;
  132.         }
  133.     
  134.                                                          // grab an offscreen draw area
  135.     err = NewGWorld( &gOffScreenGWorld, 32, &imageBounds, nil, curDevice, useTempMem);
  136.     if (err) {
  137.         TellUser("\pCan't get offscreen buffer.", err);
  138.         return nil;
  139.         }
  140.     
  141.     offPix = GetGWorldPixMap( gOffScreenGWorld );        // grab the pixmap
  142.     
  143.     LockPixels(offPix);                                    // lock it down
  144.     
  145.     SetGWorld( gOffScreenGWorld, nil );                    // use the GWorld to draw into
  146.     
  147.     GraphicsImportSetBoundsRect(gi, &imageBounds);         // set bounds
  148.     
  149.     GetGWorld( &newPort, &newDevice );                    // get port/device of GWorld
  150.     
  151.     GraphicsImportSetGWorld( gi, newPort, newDevice );    // inform QT of the new world order
  152.     
  153.     GraphicsImportDraw(gi);                                // draw into back buffer
  154.     
  155.     CloseComponent(gi);                                    // close the QT component
  156.     
  157.     SetGWorld( curPort, curDevice );                     // restore the old port & device
  158.     
  159.     return offPix;                                        // return the pixmap handle
  160.  
  161.  
  162. // -------------------- CreateWinPict() --------------- 
  163. // Take a snapshot of a given window.
  164. PicHandle CreateWinPict( WindowPtr pictWindow )
  165. {
  166.     PicHandle        hPict;    
  167.     
  168.     SetPort(pictWindow); // not much good if we don't do this!
  169.     
  170.     ClipRect( &pictWindow->portRect );    
  171.         
  172.     hPict = OpenPicture( &pictWindow->portRect );    // start recording
  173.  
  174.     BlankIt();                  // normalize colors to prevent artifacts
  175.     
  176.     CopyBits( &pictWindow->portBits, &pictWindow->portBits,
  177.             &pictWindow->portRect, &pictWindow->portRect, srcCopy, 0L );
  178.  
  179.     ClosePicture();              // stop recording
  180.         
  181.     return( hPict );
  182. }
  183.  
  184.  
  185. /* --------------------- BlankIt() ------------------- */
  186. // Call this before any call to CopyBits(). Or else risk
  187. // unwanted colorizing artifacts.
  188. void BlankIt(void)
  189. {
  190.     RGBColor        blackRGB = {0, 0, 0};
  191.     RGBColor        whiteRGB = {65535, 65535, 65535};    
  192.     
  193.     RGBForeColor(&blackRGB);        
  194.     RGBBackColor(&whiteRGB);        
  195. }
  196.